package com.nova.android.tvlauncher.ext

import android.content.Context
import android.os.Build
import android.os.storage.StorageManager
import android.os.storage.StorageVolume
import androidx.annotation.RequiresApi
import com.nova.android.tvlauncher.bean.atv_bean.Notification
import com.nova.android.tvlauncher.bean.atv_bean.StorageType
import com.shudong.lib_base.ext.appContext
import java.io.File
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method

@RequiresApi(Build.VERSION_CODES.N)
fun Context.getStorageDeviceList(): MutableList<Notification.StorageDevice> {
    val storageManager = getSystemService(Context.STORAGE_SERVICE) as StorageManager
    val storageDevices = mutableListOf<Notification.StorageDevice>()

    try {
        // 通过反射获取 VolumeInfo 列表
        val getVolumesMethod = StorageManager::class.java.getMethod("getVolumes")
        val volumes = getVolumesMethod.invoke(storageManager) as? List<Any> ?: emptyList()

        // 获取 StorageVolume 列表（路径、描述、UUID）
        val storageVolumes = getStorageVolumes()

        // 反射拿 VolumeInfo 的 state 常量
        val volumeInfoClass = Class.forName("android.os.storage.VolumeInfo")
        val stateMountedField = volumeInfoClass.getField("STATE_MOUNTED")
        val STATE_MOUNTED = stateMountedField.getInt(null)

        for (volume in volumes) {
            try {
                // 取 state
                val state = volume.javaClass.getMethod("getState").invoke(volume) as? Int ?: continue
                if (state != STATE_MOUNTED) {
                    // 未挂载的卷，跳过
                    continue
                }

                // 取 path（可能为 null，所以加 ?）
                val volumeFile = volume.javaClass.getMethod("getPath").invoke(volume) as? File ?: continue
                val volumePath = volumeFile.path

                // 取 DiskInfo（可能为 null）
                val disk = volume.javaClass.getMethod("getDisk").invoke(volume) ?: continue
                val volumeType = disk.getStorageType()
                val volumeDescription = disk.getVolumeName()

                var storageVolumeName = ""
                var storageUID = ""

                // 匹配 StorageVolume 的路径
                storageVolumes.forEach {
                    val storageVolumePath = it.first
                    val volumeDesc = it.second
                    val uuid = it.third
                    if (volumePath == storageVolumePath) {
                        storageVolumeName = volumeDesc
                        storageUID = uuid
                    }
                }

                if (volumeType != StorageType.Unknown) {
                    storageDevices.add(
                        Notification.StorageDevice(
                            volumePath,
                            volumeType,
                            volumeDescription,
                            storageVolumeName,
                            storageUID
                        )
                    )
                }

            } catch (innerE: Exception) {
                innerE.printStackTrace()
                // 单个 volume 出错不影响整体
                continue
            }
        }

    } catch (e: Exception) {
        e.printStackTrace()
    }

    return storageDevices
}


/**
 * 参数类型必须是 DiskInfo 对象 * @param disk
 */
fun Any?.getStorageType(): StorageType {

    if (this == null) return StorageType.Unknown
    return try {
        //当前存储是否是TF卡（Boolean类型）
        val isTFCard = this.javaClass.getMethod("isSd").invoke(this) as Boolean
        //当前存储是否是USB存储（Boolean类型）
        val isUsb = this.javaClass.getMethod("isUsb").invoke(this) as Boolean

        when {
            //返回TF类型
            isTFCard -> StorageType.TFCard
            //返回USB类型
            isUsb -> StorageType.USBStorage
            //未知类型
            else -> StorageType.Unknown
        }
    } catch (e: NoSuchMethodException) {
        e.printStackTrace()
        StorageType.Unknown
    } catch (e: IllegalAccessException) {
        e.printStackTrace()
        StorageType.Unknown
    } catch (e: InvocationTargetException) {
        e.printStackTrace()
        StorageType.Unknown
    }
}


/**
 * 获取VolumeInfo的description
 */
fun Any?.getVolumeName(): String {
    if (this == null) return "Unknown"

    return try {
        val getDescriptionMethod = this.javaClass.getMethod("getDescription")
        getDescriptionMethod.invoke(this) as String
    } catch (e: NoSuchMethodException) {
        e.printStackTrace()
        "Unknown"
    } catch (e: IllegalAccessException) {
        e.printStackTrace()
        "Unknown"
    } catch (e: InvocationTargetException) {
        e.printStackTrace()
        "Unknown"
    }
}

@RequiresApi(Build.VERSION_CODES.N)
fun StorageVolume.getStorageVolumeUuid(): String? {
    return try {
        val getUuidMethod: Method = StorageVolume::class.java.getDeclaredMethod("getUuid")
        getUuidMethod.isAccessible = true
        getUuidMethod.invoke(this) as String?
    } catch (e: Exception) {
        e.printStackTrace()
        null
    }
}


/**
 * 获取StorageVolumes
 */
@RequiresApi(Build.VERSION_CODES.N)
fun Context.getStorageVolumes(): MutableList<Triple<String, String, String>> {
    val storageInfoList = mutableListOf<Triple<String, String, String>>()
    val storageManager = getSystemService(Context.STORAGE_SERVICE) as StorageManager
    val volumeList = storageManager.storageVolumes
    val volumeInfoClass: Class<*> = Class.forName("android.os.storage.StorageVolume")
    for (volume in volumeList) {
        try {
            val mPath = if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
                volume.directory?.path
            } else {
                //val volumeInfoGetDiskMethod = volumeInfoClass.getMethod("getPathFile")
                //volumeInfoGetDiskMethod.invoke(volume) as? File
                val volumeInfoGetDiskMethod = volumeInfoClass.getMethod("getPath")
                volumeInfoGetDiskMethod.invoke(volume) as? String
            }

            val uuid = volume.getStorageVolumeUuid()
            //"当前的UUID是：$uuid".e("zengyue")

            if (mPath == null) continue
            storageInfoList.add(Triple(mPath, volume.getDescription(this), uuid ?: ""))

        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
    return storageInfoList
}

/**
 * 根据路径判断是否是TF卡* @param path
 */
fun String.isTFCard(): Pair<Boolean, String> {
    val storageList = appContext.getStorageDeviceList()
    storageList.forEach {
        if (this.contains(it.path)) {
            return Pair(it.storageType == StorageType.TFCard, it.volumeName)
        }
    }
    return Pair(false, "")
}

/**
 * 根据路径判断是否是TF卡* @param path
 */
fun String.findDeviceByPath(): Notification.StorageDevice? {
    val storageList = appContext.getStorageDeviceList()
    storageList.forEach {
        if (this.contains(it.path)) {
            return it
        }
    }
    return null
}